package com.whz.mlc.provider.proxy;

import com.whz.generic.parameter.ExpressionParserUtils;
import com.whz.mlc.cache.data.MlcCacheEntityWrapper;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.annotation.Annotation;

/**
 * @author whz
 * 2021/8/17
 */
@Slf4j
public abstract class ProxyFilterBase<A extends Annotation> implements ProxyFilter {

    @Override
    public boolean filter(MethodInvocation invocation) {
        return getAnnotation(invocation) != null;
    }

    @Override
    public void onBefore(MethodInvocation invocation) {
        log.debug("Before->Proxy Filter Class:{}", getClass().getSimpleName());
    }

    @Override
    public void onAfter(MethodInvocation invocation, Object returnValue) {

    }

    @Override
    public void onError(Throwable throwable) {
        log.error("tmc cache error.", throwable);
    }

    protected abstract Class<A> getAnnotationClass();

    /**
     * 查询指定的方法注释
     *
     * @param invocation 回调的方法
     * @return 方法注释
     */
    protected A getAnnotation(MethodInvocation invocation) {
        return AnnotationUtils.findAnnotation(invocation.getMethod(), getAnnotationClass());
    }

    /**
     * 查询目标对象内的getCacheName()后构建{@link MlcCacheEntityWrapper}对象
     *
     * @param target 目标对象
     * @return {@link MlcCacheEntityWrapper}对象
     */
    protected MlcCacheEntityWrapper<Object> createDataWrapper(Object target) {
        Object cacheName = ExpressionParserUtils.parseExpression("#root.getCacheName()", target);
        MlcCacheEntityWrapper<Object> dataWrapper = new MlcCacheEntityWrapper<>();
        dataWrapper.setCacheName(String.valueOf(cacheName));
        return dataWrapper;
    }
}